expression: Add GtkObjectExpression
authorBenjamin Otte <otte@redhat.com>
Tue, 26 Nov 2019 17:59:34 +0000 (18:59 +0100)
committerMatthias Clasen <mclasen@redhat.com>
Sat, 30 May 2020 21:42:09 +0000 (17:42 -0400)
Weak refs break cycles...

docs/reference/gtk/gtk4-sections.txt
gtk/gtkexpression.c
gtk/gtkexpression.h

index 89978fbcace9e810166d9a5244e9a102ce95d0d7..35b6d349460ac9b1d4b448d47dba045a2f8851ff 100644 (file)
@@ -7091,7 +7091,7 @@ gtk_property_expression_new
 gtk_property_expression_new_for_pspec
 gtk_constant_expression_new
 gtk_constant_expression_new_for_value
-gtk_object_expression
+gtk_object_expression_new
 gtk_closure_expression_new
 gtk_cclosure_expression_new
 
index dbd100c7674e14f2eccad4638d6753fe54662b1b..d6b0c7820624b2a046de7ff71e20e9f74241fac7 100644 (file)
@@ -208,6 +208,85 @@ gtk_constant_expression_new_for_value (const GValue *value)
   return (GtkExpression *) result;
 }
 
+/*** OBJECT ***/
+
+typedef struct _GtkObjectExpression GtkObjectExpression;
+
+struct _GtkObjectExpression
+{
+  GtkExpression parent;
+
+  GObject *object;
+};
+
+static void
+gtk_object_expression_weak_ref_cb (gpointer  data,
+                                   GObject  *object)
+{
+  GtkObjectExpression *self = (GtkObjectExpression *) data;
+
+  self->object = NULL;
+}
+
+static void
+gtk_object_expression_finalize (GtkExpression *expr)
+{
+  GtkObjectExpression *self = (GtkObjectExpression *) expr;
+
+  if (self->object)
+    g_object_weak_unref (self->object, gtk_object_expression_weak_ref_cb, self);
+}
+
+static gboolean
+gtk_object_expression_evaluate (GtkExpression *expr,
+                                gpointer       this,
+                                GValue        *value)
+{
+  GtkObjectExpression *self = (GtkObjectExpression *) expr;
+
+  if (self->object == NULL)
+    return FALSE;
+
+  g_value_init (value, gtk_expression_get_value_type (expr));
+  g_value_set_object (value, self->object);
+  return TRUE;
+}
+
+static const GtkExpressionClass GTK_OBJECT_EXPRESSION_CLASS =
+{
+  sizeof (GtkObjectExpression),
+  "GtkObjectExpression",
+  gtk_object_expression_finalize,
+  gtk_object_expression_evaluate
+};
+
+/**
+ * gtk_object_expression_new:
+ * @object: (transfer none): object to watch
+ *
+ * Creates an expression evaluating to the given @object with a weak reference.
+ * Once the @object is disposed, it will fail to evaluate.
+ * This expression is meant to break reference cycles.
+ *
+ * If you want to keep a reference to @object, use gtk_constant_expression_new().
+ *
+ * Returns: a new #GtkExpression
+ **/
+GtkExpression *
+gtk_object_expression_new (GObject *object)
+{
+  GtkObjectExpression *result;
+
+  g_return_val_if_fail (G_IS_OBJECT (object), NULL);
+
+  result = gtk_expression_alloc (&GTK_OBJECT_EXPRESSION_CLASS, G_OBJECT_TYPE (object));
+
+  result->object = object;
+  g_object_weak_ref (object, gtk_object_expression_weak_ref_cb, result);
+
+  return (GtkExpression *) result;
+}
+
 /*** PROPERTY ***/
 
 typedef struct _GtkPropertyExpression GtkPropertyExpression;
index 270761e8ab2a00a2b02cf303aaf09185151c3a6b..3df3788d1b3c8c9a9f839bd8dbe9f56d8686c9cb 100644 (file)
@@ -59,6 +59,8 @@ GtkExpression *         gtk_constant_expression_new             (GType
 GDK_AVAILABLE_IN_ALL
 GtkExpression *         gtk_constant_expression_new_for_value   (const GValue                   *value);
 GDK_AVAILABLE_IN_ALL
+GtkExpression *         gtk_object_expression_new               (GObject                        *object);
+GDK_AVAILABLE_IN_ALL
 GtkExpression *         gtk_closure_expression_new              (GType                           value_type,
                                                                  GClosure                       *closure,
                                                                  guint                           n_params,